package com.chaike.hsq.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.chaike.common.util.StringUC;
import com.chaike.common.util.ValidateUC;
import com.chaike.core.json.JsonUtil;
import com.chaike.hsq.bean.request.HuiShouQianRequest;
import com.chaike.hsq.bean.request.pay.AppletsPayRequest;
import com.chaike.hsq.bean.request.pay.PayNotifyRequest;
import com.chaike.hsq.bean.request.pay.PayQueryRequest;
import com.chaike.hsq.bean.request.pay.RefundRequest;
import com.chaike.hsq.bean.response.BaseHsqResponse;
import com.chaike.hsq.bean.response.pay.AppletsPayNotifyResponse;
import com.chaike.hsq.bean.response.pay.AppletsPayResponse;
import com.chaike.hsq.bean.response.pay.PayQueryResponse;
import com.chaike.hsq.bean.response.pay.RefundResponse;
import com.chaike.hsq.consts.HsqConsts;
import com.chaike.hsq.exception.HuiShouQianCheckException;
import com.chaike.hsq.exception.HuiShouQianException;
import com.chaike.hsq.properties.HuiShouQianProperties;
import com.chaike.hsq.service.HuiShouQianService;
import com.chaike.hsq.storage.HsqConfigStorage;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.util.Map;

/**
 * 慧收钱 支付 服务.
 *
 * @author Luo
 * @version 1.0
 * @date 2022-01-06 17:11
 */
@Slf4j
public class HsqPayService {

    private final HuiShouQianService huiShouQianService;

    public HsqPayService(final HuiShouQianService huiShouQianService) {
        this.huiShouQianService = huiShouQianService;
    }

    /**
     * 小程序支付.
     *
     * @param request 请求参数
     * @return 响应
     * @throws HuiShouQianException 接口异常
     */
    public AppletsPayResponse appletsPay(final AppletsPayRequest request) throws HuiShouQianException {
        ValidateUC.notNull(request, HuiShouQianCheckException.class, "支付请求参数不能为空！");
        log.info("[慧收钱] - 小程序支付请求参数：{}", request.getJsonParams());
        // 执行请求调度
        BaseHsqResponse response = this.executeInternal(request);
        return response.toResult(AppletsPayResponse.class);
    }

    /**
     * 支付结果查询.
     *
     * @param request 请求参数
     * @return 结果
     * @throws HuiShouQianException 接口异常
     */
    public PayQueryResponse payQuery(final PayQueryRequest request) throws HuiShouQianException {
        ValidateUC.notNull(request, HuiShouQianCheckException.class, "支付结果查询请求参数不能为空！");
        log.info("[慧收钱] - 支付结果查询请求参数：{}", request.getJsonParams());
        // 执行请求调度
        BaseHsqResponse response = this.executeInternal(request);
        return response.toResult(PayQueryResponse.class);
    }

    /**
     * 解析小程序支付回调通知结果.
     *
     * @param notifyData 通知数据
     * @return 结果
     * @throws HuiShouQianException 接口异常
     */
    public AppletsPayNotifyResponse parseAppletsPayNotifyResult(final String notifyData) throws HuiShouQianException {
        ValidateUC.strNotEmpty(notifyData, HuiShouQianCheckException.class, "通知数据为空！");
        log.info("[慧收钱] - 解析小程序支付回调通知数据：{}", notifyData);
        // 解析公共通知响应数据
        PayNotifyRequest request = BeanUtil.toBean(StringUC.splitToMap(notifyData), PayNotifyRequest.class);
        log.info("[慧收钱] - 解析小程序支付回调通知数据完成：{}", request.getJsonParams());
        // 解密数据
        String decrypt = huiShouQianService.decrypt(request.getSignContent());
        return JsonUtil.parse(decrypt, AppletsPayNotifyResponse.class);
    }

    /**
     * 退款.
     *
     * @param request 请求参数
     * @return 响应
     * @throws HuiShouQianException 接口异常
     */
    public RefundResponse refund(final RefundRequest request) throws HuiShouQianException {
        ValidateUC.notNull(request, HuiShouQianCheckException.class, "退款请求参数不能为空！");
        log.info("[慧收钱] - 退款请求参数：{}", request.getJsonParams());
        // 执行请求调度
        BaseHsqResponse response = this.executeInternal(request);
        return response.toResult(RefundResponse.class);
    }

    /**
     * 执行支付请求调用.
     *
     * @param request 请求
     * @param <T>     具体的API响应类
     * @return 具体的API响应结果
     * @throws HuiShouQianException API调用异常
     */
    private <T> BaseHsqResponse executeInternal(final HuiShouQianRequest<T> request) throws HuiShouQianException {
        // 获取配置信息
        HsqConfigStorage hsqConfigStorage = huiShouQianService.getHsqConfigStorage();
        HuiShouQianProperties.Pay pay = hsqConfigStorage.getPay();
        // 公共请求参数
        Map<String, Object> publicParams = Maps.newHashMap();
        publicParams.put(HsqConsts.METHOD, request.getMethodName());
        publicParams.put(HsqConsts.VERSION, pay.getVersion());
        publicParams.put(HsqConsts.MERCHANT_NO, request.getMerchantNo());
        // 加密业务请求参数数据
        publicParams.put(HsqConsts.SIGN_CONTENT, huiShouQianService.encrypt(request.getJsonParams()));
        BaseHsqResponse response = null;
        try {
            // 发起请求
            response = huiShouQianService.postObject(pay.getApiUrl(), publicParams);
        } catch (HuiShouQianException e) {
            throw e;
        } catch (Exception e) {
            log.error("调用慧收钱支付系统接口发生异常：{}", ExceptionUtils.getStackTrace(e));
        }
        return response;
    }

}
